package cn.xianshu.userdetails;

import cn.xianshu.domain.Login;
import cn.xianshu.domain.Permission;
import cn.xianshu.mapper.PermissionMapper;
import cn.xianshu.service.impl.LoginServiceImpl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用来提供给security的用户信息的service，
 * 我们需要复写 loadUserByUsername 方法返回数据库中的用户信息
 */

@Service
@Slf4j
public class JDBCUserDetailService implements UserDetailsService {

    @Autowired
    private LoginServiceImpl loginService;

    @Autowired
    private PermissionMapper permissionMapper;



    /**
     * 加载数据库中的认证的用户的信息：用户名，密码，用户的权限列表
     * @param username: 该方法把username传入进来，我们通过username查询用户的信息
    (密码，权限列表等)然后封装成 UserDetails进行返回 ，交给security 。
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
        // 查询用户是否存在
        EntityWrapper wrapper = new EntityWrapper();
        wrapper.eq("username",username);
        Login login = loginService.selectOne(wrapper);
        if (login == null){
            throw new UsernameNotFoundException("用户名不存在!");
        }

        // 查询用户的权限
        List<GrantedAuthority> authorities = new ArrayList<>();
        List<Permission> permission = permissionMapper.selectPermissionsByUserId(login.getId());
        if (!permission.isEmpty()){
            authorities = permission.stream().map(p -> new SimpleGrantedAuthority(p.getSn())).collect(Collectors.toList());
        }


        log.info("加载用户的权限 {}", authorities);
        Map<String, Object> map = new HashMap<>();
        map.put("id", login.getId());
        map.put("username", login.getUsername());
        map.put("tenantId", login.getTenantId());
        map.put("tenantName", login.getTenantName());
        return new User(JSON.toJSONString(map), // 将map装换为json
                login.getPassword(),
                login.getEnabled(), login.getAccountNonExpired(), login.getCredentialsNonExpired(), login.getAccountNonLocked(),
                authorities);
    }
}
